﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft;
using Newtonsoft.Json;

namespace MiniMax.Library
{
    public class T2A_Pro
    {
        public string ApiAddress = @"https://api.minimax.chat/v1/t2a_pro";

        HttpClient client = new HttpClient();

        public async Task<T2A_ProRequestResponse> Send(T2A_ProRequest request)
        {
            T2A_ProRequestResponse response = new T2A_ProRequestResponse();

            HttpRequestMessage httpRequest = new HttpRequestMessage();
            httpRequest.Method = HttpMethod.Post;
            string requestApi = ApiAddress + "?GroupId=" + request.groupId;
            httpRequest.RequestUri = new Uri(requestApi);
            httpRequest.Headers.Authorization = new System.Net.Http.Headers.AuthenticationHeaderValue("Bearer", request.header.Authorization);
            
            StringContent content = new StringContent(JsonConvert.SerializeObject(request.data),Encoding.UTF8, "application/json");
            httpRequest.Content = content;

            HttpResponseMessage httpResponse = await client.SendAsync(httpRequest);

            if (httpResponse.IsSuccessStatusCode == true)
            {
                string responseStr = await httpResponse.Content.ReadAsStringAsync();
                response = JsonConvert.DeserializeObject(responseStr, typeof(T2A_ProRequestResponse)) as T2A_ProRequestResponse;
                return response;
            }

            return response;
        }

        /// <summary>
        /// title文件转SRT文件
        /// </summary>
        /// <param name="titlePath"></param>
        /// <param name="srtPath"></param>
        public static void Title2Srt(string titlePath, string srtPath)
        {
            using (FileStream fsTitle = new FileStream(titlePath, FileMode.Open, FileAccess.Read))
            {
                using (FileStream fsSrt = new FileStream(srtPath, FileMode.Create, FileAccess.ReadWrite))
                {
                    byte[] buffer = new byte[fsTitle.Length];
                    fsTitle.Read(buffer, 0, buffer.Length);
                    string titleContent = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                    List<JsonData> jsonDatas = JsonConvert.DeserializeObject<List<JsonData>>(titleContent);
                    TimeSpan startTime = new TimeSpan(0, 0, 0);
                    for (int i = 0, j = 1; i < jsonDatas.Count; i++, j++)
                    {
                        /*
                            2404
                            02:02:20,820 --> 02:02:23,971
                            你和钱对我都不重要
                            
                            2405
                            02:02:25,740 --> 02:02:26,889
                            那谁重要？
                            
                            2406
                            02:02:30,900 --> 02:02:34,017
                            没有你，对我很重要
                         */
                        StringBuilder strSub = new StringBuilder();
                        //序号
                        strSub.AppendLine(j.ToString());

                        //时间段
                        long startMilliseconds = Convert.ToInt64(Math.Floor(jsonDatas[i].time_begin));
                        long startHour = (startMilliseconds) / (1000 * 60 * 60);
                        long startMinute = (startMilliseconds / (1000 * 60)) % 60;
                        long startSecond = (startMilliseconds / 1000) % 60;
                        long startMillisecond = startMilliseconds % 1000;

                        long endMilliseconds = Convert.ToInt64(Math.Floor(jsonDatas[i].time_end));
                        long endHour = (endMilliseconds) / (1000 * 60 * 60);
                        long endMinute = (endMilliseconds / (1000 * 60)) % 60;
                        long endSecond = (endMilliseconds / 1000) % 60;
                        long endMillisecond = endMilliseconds % 1000;
                        strSub.AppendLine(
                            string.Format("{0}:{1}:{2}.{3}", startHour, startMinute, startSecond, startMillisecond) +
                            " --> " +
                            string.Format("{0}:{1}:{2}.{3}", endHour, endMinute, endSecond, endMillisecond)
                            );
                        //显示的文本
                        strSub.AppendLine(jsonDatas[i].text);
                        strSub.AppendLine();
                        byte[] bufferWrite = Encoding.UTF8.GetBytes(strSub.ToString());
                        fsSrt.Write(bufferWrite, 0, bufferWrite.Length);
                        fsSrt.Flush();
                    }
                }
            }


        }

        /// <summary>
        /// title内容流SRT字幕文件并保存
        /// </summary>
        /// <param name="titleStream">title内容流</param>
        /// <param name="srtPath">SRT文件保存路径</param>
        public static void Title2Srt_Save(Stream titleStream, string srtPath)
        {
            using (Stream fsTitle = titleStream)
            {
                using (FileStream fsSrt = new FileStream(srtPath, FileMode.Create, FileAccess.ReadWrite))
                {
                    byte[] buffer = new byte[fsTitle.Length];
                    fsTitle.Read(buffer, 0, buffer.Length);
                    string titleContent = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                    List<JsonData> jsonDatas = JsonConvert.DeserializeObject<List<JsonData>>(titleContent);
                    TimeSpan startTime = new TimeSpan(0, 0, 0);
                    StringBuilder strSub = new StringBuilder();
                    for (int i = 0, j = 1; i < jsonDatas.Count; i++, j++)
                    {
                        //序号
                        strSub.AppendLine(j.ToString());

                        //时间段
                        long startMilliseconds = Convert.ToInt64(Math.Floor(jsonDatas[i].time_begin));
                        long startHour = (startMilliseconds) / (1000 * 60 * 60);
                        long startMinute = (startMilliseconds / (1000 * 60)) % 60;
                        long startSecond = (startMilliseconds / 1000) % 60;
                        long startMillisecond = startMilliseconds % 1000;

                        long endMilliseconds = Convert.ToInt64(Math.Floor(jsonDatas[i].time_end));
                        long endHour = (endMilliseconds) / (1000 * 60 * 60);
                        long endMinute = (endMilliseconds / (1000 * 60)) % 60;
                        long endSecond = (endMilliseconds / 1000) % 60;
                        long endMillisecond = endMilliseconds % 1000;
                        strSub.AppendLine(
                            string.Format("{0}:{1}:{2}.{3}", startHour, startMinute, startSecond, startMillisecond) +
                            " --> " +
                            string.Format("{0}:{1}:{2}.{3}", endHour, endMinute, endSecond, endMillisecond)
                            );
                        //显示的文本
                        strSub.AppendLine(jsonDatas[i].text);
                        strSub.AppendLine();
                    }
                    byte[] bufferWrite = Encoding.UTF8.GetBytes(strSub.ToString());
                    fsSrt.Write(bufferWrite, 0, bufferWrite.Length);
                    fsSrt.Flush();
                }
            }


        }

        /// <summary>
        /// title内容流转SRT内容流
        /// </summary>
        /// <param name="titleStream">title内容流转</param>
        /// <returns>SRT内容流</returns>
        public static Stream Title2Srt(Stream titleStream)
        {
            using (Stream fsTitle = titleStream)
            {
                byte[] buffer = new byte[fsTitle.Length];
                fsTitle.Read(buffer, 0, buffer.Length);
                string titleContent = Encoding.UTF8.GetString(buffer, 0, buffer.Length);
                List<JsonData> jsonDatas = JsonConvert.DeserializeObject<List<JsonData>>(titleContent);
                TimeSpan startTime = new TimeSpan(0, 0, 0);

                //要写入的SRT字幕内容
                StringBuilder strSub = new StringBuilder();
                for (int i = 0, j = 1; i < jsonDatas.Count; i++, j++)
                {
                    //序号
                    strSub.AppendLine(j.ToString());
                    //时间段
                    long startMilliseconds = Convert.ToInt64(Math.Floor(jsonDatas[i].time_begin));
                    long startHour = (startMilliseconds) / (1000 * 60 * 60);
                    long startMinute = (startMilliseconds / (1000 * 60)) % 60;
                    long startSecond = (startMilliseconds / 1000) % 60;
                    long startMillisecond = startMilliseconds % 1000;

                    long endMilliseconds = Convert.ToInt64(Math.Floor(jsonDatas[i].time_end));
                    long endHour = (endMilliseconds) / (1000 * 60 * 60);
                    long endMinute = (endMilliseconds / (1000 * 60)) % 60;
                    long endSecond = (endMilliseconds / 1000) % 60;
                    long endMillisecond = endMilliseconds % 1000;
                    strSub.AppendLine(
                        string.Format("{0}:{1}:{2}.{3}", startHour, startMinute, startSecond, startMillisecond) +
                        " --> " +
                        string.Format("{0}:{1}:{2}.{3}", endHour, endMinute, endSecond, endMillisecond)
                        );

                    //字幕
                    strSub.AppendLine(jsonDatas[i].text);
                    strSub.AppendLine();
                }
                byte[] bufferWrite = Encoding.UTF8.GetBytes(strSub.ToString());
                Stream srtStream = new MemoryStream();

                srtStream.Write(bufferWrite, 0, bufferWrite.Length);
                return srtStream;
            }
        }

        private class JsonData
        {
            public string text { get; set; }

            public double time_begin { get; set; }

            public double time_end { get; set; }
            public int text_begin { get; set; }
            public int text_end { get; set; }

        }
    }

    #region Request
    public class T2A_ProRequest
    {
        public T2A_ProRequestHeader header { get; set; } = new T2A_ProRequestHeader();

        public string groupId { get; set; } = "";

        public T2A_ProRequestBody data { get; set; } = new T2A_ProRequestBody();
    }
    public class T2A_ProRequestHeader
    {
        // API密钥，必填项
        public string Authorization { get; set; } = "";

        // 请求内容类型，必填项
        public string Content_Type { get; set; } = "";
    }

    public class T2A_ProRequestBody
    {
        /// <summary>
        /// 调用的模型版本，必填项
        /// </summary>
        public string model { get; set; } = "speech-02";

        /// <summary>
        /// 请求的音色编号，可选项
        /// </summary>
        public string voice_id { get; set; } = "";

        /// <summary>
        /// 混合音色相关信息，可选项
        /// </summary>
        public List<T2A_ProRequestTimberWeight>? timber_weights { get; set; }

        /// <summary>
        /// 生成声音的语速，可选项，范围[0.5, 2]
        /// </summary>
        public double speed { get; set; } = 1.0;

        /// <summary>
        /// 生成声音的音量，可选项，范围（0, 10]
        /// </summary>
        public double vol { get; set; } = 1.0;

        /// <summary>
        /// 生成声音的音频格式，可选项，默认值为mp3
        /// </summary>
        public string output_format { get; set; } = "mp3";

        /// <summary>
        /// 生成声音的语调，可选项，范围[-12, 12]
        /// </summary>
        public int pitch { get; set; } = 0;

        /// <summary>
        /// 需要生成的文本，必填项，长度限制<50000字符
        /// </summary>
        public string text { get; set; } = "";

        /// <summary>
        /// 生成声音的采样率，必填项，范围[16000,24000,32000]
        /// </summary>
        public int audio_sample_rate { get; set; } = 32000;

        /// <summary>
        /// 生成声音的比特率，必填项，范围[32000, 64000，128000]
        /// </summary>
        public int bitrate { get; set; } = 128000;

        /// <summary>
        /// 替换需要特殊标注的文字、符号及对应的注音，可选项
        /// </summary>
        public string[]? char_to_pitch { get; set; }
    }
    /// <summary>
    /// 混合音色权重类，包含音色编号和权重
    /// </summary>
    public class T2A_ProRequestTimberWeight
    {
        /// <summary>
        /// 请求的音色编号
        /// </summary>
        public string voice_id { get; set; } = "";

        /// <summary>
        /// 权重，范围[1, 100]
        /// </summary>
        public int weight { get; set; } = 25;
    }

    /// <summary>
    /// 替换字符类，用于替换需要特殊标注的文字、符号及对应的注音
    /// </summary>
    public class T2A_ProRequestCharToPitch
    {
        /// <summary>
        /// 原始文本
        /// </summary>
        public string OriginalText { get; set; } = "";

        /// <summary>
        /// 替换后的文本
        /// </summary>
        public string ReplacementText { get; set; } = "";
    }
    #endregion

    #region Response
    public class T2A_ProRequestResponse
    {
        /// <summary>
        /// 生成id,用于在咨询/反馈时帮助定位问题
        /// </summary>
        public string trace_id { get; set; }

        /// <summary>
        /// 合成的音频下载链接
        /// </summary>
        public string audio_file { get; set; }

        /// <summary>
        /// 合成的字幕下载链接
        /// </summary>
        public string subtitle_file {  get; set; }

        public T2A_ProRequestExtraInfo extra_info { get; set; }

        public BaseResp base_resp { get; set; }
    }

    public class T2A_ProRequestExtraInfo
    {
        /// <summary>
        /// 音频时长
        /// </summary>
        public Int64 audio_length { get; set; }

        /// <summary>
        /// 采样率
        /// </summary>
        public Int64 audio_sample_rate { get; set; }

        /// <summary>
        /// 音频大小
        /// </summary>
        public Int64 audio_size { get; set; }

        /// <summary>
        /// 比特率
        /// </summary>
        public Int64 bitrate { get; set; }

        /// <summary>
        /// 可读字数
        /// </summary>
        public Int64 word_count { get; set; }

        /// <summary>
        /// 非法字符占比
        /// </summary>
        public float invisible_character_ratio { get; set; }

        /// <summary>
        /// 消费字符数
        /// </summary>
        public Int64 usage_characters { get;set; }
    }
    #endregion
}
